/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦，本文采用木兰宽松许可证第2版]
 * 
 * https://zhiqim.org/project/zhiqim_kit/zhiqim_git.htm
 *
 * ZhiqimGit is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.git.http.model;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashSet;
import java.util.Set;

import org.zhiqim.git.objer.objectid.ObjectId;
import org.zhiqim.git.refer.Ref;
import org.zhiqim.git.refer.ref.ObjectIdRef;
import org.zhiqim.git.util.GitStreams;
import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.extend.LinkedMapSV;
import org.zhiqim.kernel.extend.MapSV;
import org.zhiqim.kernel.util.Strings;

/**
 * 公告对象
 * 001f# service=git-receive-pack
 * 0000008fdbf7968225c3f9bfc281150e6594650e66f7c8b1 refs/heads/master
 * 0000
 *
 * @version v1.4.1 @author zouzhigang 2018-8-3 新建与整理
 */
public class Advertiser implements SignConstants
{
    private String service;
    private final Set<String> capablities = new LinkedHashSet<>();
    private final MapSV<Ref> refs = new LinkedMapSV<>();
    
    public void parse(InputStream in) throws IOException
    {
        //第一行，显示服务
        String line = GitStreams.readString(in);
        this.service = Strings.trimLeft(line, "# service=");

        //跳过END
        GitStreams.readString(in);
        
        //第二行，显示引用列表和能力
        boolean first = true;
        while (true)
        {
            line = GitStreams.readString(in);
            if (line == null)
                break;
            
            if (first)
            {
                first = false;
                int nul = line.indexOf('\0');
                if (nul >= 0)
                {
                    for (String c : line.substring(nul + 1).split(" "))
                        capablities.add(c);
                    
                    line = line.substring(0, nul);
                }
            }
        
            String oid = line.substring(0, 40);
            String name = line.substring(41);
            Ref ref = new ObjectIdRef(name, ObjectId.parse(oid));
            refs.put(name, ref);
        }
    }
    
    public boolean contains(String capablitie)
    {
        return capablities.contains(capablitie);
    }
    
    public MapSV<Ref> getRefList()
    {
        return refs;
    }
    
    public boolean containsRef(String name)
    {
        return refs.containsKey(name);
    }
    
    public String toString()
    {
        try
        {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            GitStreams.writeString(out, "# service=" + service + "\n");
            GitStreams.writeEnd(out);
            
            boolean first = true;
            StringBuilder strb = new StringBuilder();
            for (Ref ref : refs.values())
            {
                strb.append(ref.getObjectId().toHexCharArray()).append(_SPACE_).append(ref.getName());
                if (first)
                {
                    first = false;
                    if (!capablities.isEmpty())
                    {
                        strb.append(_NUL_);
                        for (String capablitie : capablities)
                        {
                            strb.append(capablitie).append(_SPACE_);
                        }
                        strb.setLength(strb.length()-1);
                    }
                }
                strb.append(_LF_);
            }
            
            GitStreams.writeString(out, strb.toString());
            GitStreams.writeEnd(out);
            
            return new String(out.toByteArray());
        }
        catch (Exception e) 
        {
            return null;
        }
    }
}
